<template>
  <div>
    <el-upload :action="url" :accept="accept" name="file" list-type="picture-card" :on-preview="handlePictureCardPreview"
      :limit="limit" v-if="multiple" v-model:file-list="imgList" :on-success="handleAvatarSuccess"
      :before-upload="beforeUpload" :headers="headers" :on-remove="onRemove">
      <el-icon>
        <Plus />
      </el-icon>
      <template #tip>
        <div class="el-upload__tip">
          限制图片类型为{{ accept }},大小为{{ maxSize / (1024 * 1024) + 'MB' }}
          <span v-if="limit">最大上传个数为:{{ limit }}个</span>
          <span v-else-if="range">个数范围为:{{ range }}个</span>
        </div>
        <el-dialog v-model="dialogVisible" :append-to-body="true">
          <img w-full :src="dialogImageUrl" alt="Preview Image" />
        </el-dialog>
      </template>
    </el-upload>
    <div v-else>
      <el-upload class="avatar-uploader" :action="url" :accept="accept" :show-file-list="false"
        :on-success="handleAvatarSuccess" name="file" :before-upload="beforeUpload" :headers="headers">
        <img v-if="imageUrl" :src="imageUrl" class="avatar" :style="{ width: width + 'px', height: height + 'px' }" />
        <el-icon v-else class="avatar-uploader-icon">
          <Plus />
        </el-icon>
      </el-upload>
    </div>
  </div>
</template>
<script lang="ts" setup>
import { component } from '@/components/uploadImg/uploadImg'
import { dropdownItemProps, type UploadFile, type UploadProps, type UploadUserFile } from 'element-plus'
import { ref, watch } from 'vue'
import useTokenStore from '@/vendors/store/token'
import { message, MessageType } from '@/components/message/message'
const tokenStore = useTokenStore()
const headers = {
  authorization: tokenStore.getToken
}
const props = defineProps({
  limit: {
    type: Number,
  },
  range: {
    type: String,
  },
  multiple: {
    type: Boolean,
    default: false,
  },
  list: {
    type: Array<String>,
    default: [],
  },
  img: {
    type: String,
    default: '',
  },
  height: {
    type: Number,
    default: 178,
  },
  width: {
    type: Number,
    default: 178,
  },
})
const emit = defineEmits(['update:list', 'update:img'])

const { url, getApi, maxSize, accept } = component()
const imgList = ref<UploadUserFile[]>([])
const imageUrl = ref('')
watch(props, () => {
  imgList.value = []
  props.list?.forEach((url: String, index: number) => {
    imgList.value.push({
      name: index + '',
      url: url.toString(),
    })
  })
  imageUrl.value = props.img ? props.img : ''
})

const dialogImageUrl = ref('')
const dialogVisible = ref(false)
const handlePictureCardPreview: UploadProps['onPreview'] = (uploadFile) => {
  dialogImageUrl.value = uploadFile.url!
  dialogVisible.value = true
}


const handleAvatarSuccess: UploadProps['onSuccess'] = (response, uploadFile) => {
  if (props.multiple) {
    const imgs: Array<any> = []
    imgList.value.forEach((item: UploadUserFile) => {
      if (item.response) {
        imgs.push((item.response as any).data)
      } else if (item.url) {
        imgs.push(item.url)
      }
    })
    emit('update:list', imgs)
  } else {
    imageUrl.value = URL.createObjectURL(uploadFile.raw!)
    emit('update:img', (uploadFile.response as any).data)
  }
}
const onRemove: UploadProps['onRemove'] = (file, fileList) => {
  if (props.multiple) {
    const imgs: Array<any> = []
    fileList.forEach((item: UploadUserFile) => {
      imgs.push((item.url))
    })
    emit('update:list', imgs)
  } else {
    emit('update:img', '')
  }
}
const beforeUpload = (file: File) => {
  const fileSuffix = file.name.substring(file.name.lastIndexOf(".") + 1);
  if (accept.indexOf(fileSuffix) === -1) {
    message(`file only ${accept}`, MessageType.error);
    return false;
  }
  if (file.size > maxSize) {
    message(`file max size ${maxSize / (1024 * 1024)}MB`, MessageType.error);
    return false;
  }
}

getApi()
</script>
<style lang="scss" scoped>
.el-icon.avatar-uploader-icon,
.avatar {
  width: 178px;
  height: 178px;
  border-radius: 10px;
}

.el-icon.avatar-uploader-icon {
  border: 1px dashed #bbbec2;
}

.avatar {
  border: 1px dashed rgb(144, 242, 144);
}
</style>
